Imports System.Reflection
Imports Softelvdm.Controls
Imports Softelvdm.SftTreeNET

Public Class Form1

Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
    ' This sample demonstrates how sorting indicators could be used in column headers.
    ' To prepare for this sample, create a new project with a blank form and add
    ' a SftTree/NET control named sftTree1.
    ' In addition, adjust the following FromFile method to use a (small) bitmap
    ' that is located on your system.
    Dim img As Image = Bitmap.FromFile("..\\..\\test.gif")

    ' Most of this initialization code could be eliminated by designing the control.
    sftTree1.Initializing = True
    sftTree1.Columns.Count = 4
    For c As Integer = 0 To sftTree1.Columns.Count - 1
        Dim cell As CellClass = sftTree1.Headers(0, c) ' access each header cell
        cell.Text = "Column " & c.ToString() ' set the title
        If c = 1 Then cell.Image = img ' add an image to a random column header
        cell.SortIndicatorPosition = SortIndicatorPositionEnum.Default
    Next

    ' Add a few items
    Dim item As ItemClass = sftTree1.ItemCollection.Add(New String() {"Text 1", "Data 4", "44", "31"})
    item.Cells(2).TagObject = 44 ' we use the actual number for sorting, not the string
    item.Cells(3).TagObject = 31
    item = sftTree1.ItemCollection.Add(New String() {"Text 2", "Data 2", "22", "28"})
    item.Cells(2).TagObject = 22 ' we use the actual number for sorting, not the string
    item.Cells(3).TagObject = 28
    item.Cells(3).Image = img ' add an image to a random cell
    item = sftTree1.ItemCollection.Add(New String() {"Text 3", "Data 43", "11", "233"})
    item.Cells(2).TagObject = 11 ' we use the actual number for sorting, not the string
    item.Cells(3).TagObject = 233
    item = sftTree1.ItemCollection.Add(New String() {"Text 4", "Data 34", "144", "551"})
    item.Cells(2).TagObject = 144 ' we use the actual number for sorting, not the string
    item.Cells(3).TagObject = 551

    SetSorted(0) ' remember that column 0 is (already) sorted

    sftTree1.Columns.MakeOptimal(0, False)
    sftTree1.RecalcHorizontalExtent()
    sftTree1.Initializing = False
End Sub

Private m_sortedColumn As Integer = -1 ' remembers the sorted column

Private Function SetSorted(ByVal column As Integer) As Boolean
    Dim fAscending As Boolean = True ' assume new column will be ascending
    If m_sortedColumn = column And sftTree1.Headers(0, column).SortStatus = SortStatusEnum.Ascending Then
        fAscending = False ' the current column is now descending
    End If

    ' turn off sorting indicator in all column headers
    sftTree1.Headers.SetSortStatus(SortStatusEnum.NotSorted)

   ' now set the new sorting indicator
    If fAscending Then
       sftTree1.Headers(0, column).SortStatus = SortStatusEnum.Ascending
    Else
        sftTree1.Headers(0, column).SortStatus = SortStatusEnum.Descending
    End If
    m_sortedColumn = column
    Return fAscending
End Function

Private Sub SortData(ByVal e As ItemClickEventArgs)
    ' sort the column last clicked
    If e.Usage <> UsageLocationEnum.header Then ' we are not interested if the click wasn't in the header
        Return
    End If
    If e.Area <> ItemClickAreaEnum.Cell Then
        Return
    End If

    Dim fAscending As Boolean = SetSorted(e.Cell.ColumnIndex)

    Select Case e.Cell.ColumnIndex
    Case 2, 3 ' column 2 and 3 are sorted based on the TagObject property, interpreted as a long
        If fAscending Then
            sftTree1.ItemCollection.Sort(New SortTagObjectAsLongAscending(e.Cell.ColumnIndex))
        Else
            sftTree1.ItemCollection.Sort(New SortTagObjectAsLongDescending(e.Cell.ColumnIndex))
        End If
    Case Else ' column 0 and 1 are sorted based on the Text property
        If fAscending Then
            sftTree1.ItemCollection.Sort(New SortAscending(e.Cell.ColumnIndex))
        Else
            sftTree1.ItemCollection.Sort(New SortDescending(e.Cell.ColumnIndex))
        End If
    End Select
End Sub

' ItemClick event
Private Sub sftTree1_ItemClick(ByVal sender As Object, ByVal e As Softelvdm.SftTreeNET.ItemClickEventArgs) Handles sftTree1.ItemClick
    Debug.Write("** ItemClick")
    DumpValues(e)

    SortData(e)
End Sub

Private Sub sftTree1_ItemDoubleClick(ByVal sender As Object, ByVal e As Softelvdm.SftTreeNET.ItemClickEventArgs) Handles sftTree1.ItemDoubleClick
    Debug.Write("** ItemDoubleClick")
    DumpValues(e)

    SortData(e)
End Sub

' This is a small helper routine to show all properties and fields of an object
Private Sub DumpValues(ByVal o As Object)
    Dim api() As PropertyInfo = o.GetType().GetProperties()
    For Each pi As PropertyInfo In api
        Debug.Write(" " & pi.Name & " " & pi.GetValue(o, New Object() {}))
    Next
    Dim afi() As FieldInfo = o.GetType().GetFields()
    For Each fi As FieldInfo In afi
        Dim t As Object = fi.GetValue(o)
        Dim s As String = "(null)"
        If Not t Is Nothing Then s = t.ToString()
        Debug.Write(" " & fi.Name & " " & s)
    Next
    Debug.WriteLine("")
End Sub

Public NotInheritable Class SortTagObjectAsLongAscending
            Implements IComparer
    Private m_ColumnIndex As Integer

    Public Sub New(ByVal ColumnIndex As Integer)
        m_ColumnIndex = ColumnIndex
    End Sub
    Function Compare(ByVal x As Object, ByVal y As Object) As Integer Implements IComparer.Compare
        Dim i1 As ItemClass = x
        Dim i2 As ItemClass = y
        Dim l1 As Long = i1.Cells(m_ColumnIndex).TagObject
        Dim l2 As Long = i2.Cells(m_ColumnIndex).TagObject
        If l1 > l2 Then Return 1
        If l1 < l2 Then Return -1
        Return 0
    End Function
End Class
Public NotInheritable Class SortTagObjectAsLongDescending
        Implements IComparer
    Private m_ColumnIndex As Integer

    Public Sub New(ByVal ColumnIndex As Integer)
        m_ColumnIndex = ColumnIndex
    End Sub
    Function Compare(ByVal x As Object, ByVal y As Object) As Integer Implements IComparer.Compare
        Dim i1 As ItemClass = x
        Dim i2 As ItemClass = y
        Dim l1 As Long = i1.Cells(m_ColumnIndex).TagObject
        Dim l2 As Long = i2.Cells(m_ColumnIndex).TagObject
        If l1 < l2 Then Return 1
        If l1 > l2 Then Return -1
        Return 0
    End Function
End Class

End Class